﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace HMIControl
{

    public class HMIKDAButton : HMIButton
    {
        public HMIKDAButton()
        {
            this.Loaded += HMIButton_Loaded;
            this.Click += HMIButton_Click;
        }

        private void HMIButton_Click(object sender, RoutedEventArgs e)
        {
            int kda = KDA += 1;
            var ele = sender as Visual;
            var adolay = AdornerLayer.GetAdornerLayer(ele);
            var ados = adolay.GetAdorners(sender as UIElement);
            if (ados == null) return;
            adolay.Remove(ados[0]);
            KDAdorner kdaad = new KDAdorner(ele as UIElement, kda);
            adolay.Add(kdaad);
            kdaad.ShowImage = ShowAdorner;
        }

        private void HMIButton_Loaded(object sender, RoutedEventArgs e)
        {
            if (ShowAdorner)
            {
                var adolay = AdornerLayer.GetAdornerLayer(this);
                var ados = adolay.GetAdorners(this);
                KDAdorner kdaad;
                if (ados == null)
                {
                    kdaad = new KDAdorner(this, 0);
                    adolay.Add(kdaad);
                }
                ados = adolay.GetAdorners(this);
                var ado = ados.FirstOrDefault() as KDAdorner;
                if (ado != null)
                    ado.ShowImage = true;
            }

        }

        #region "Adorner实现测试" 
        public static bool GetShowAdorner(DependencyObject obj)
        {
            return (bool)obj.GetValue(ShowAdornerProperty);
        }
        public static void SetShowAdorner(DependencyObject obj, bool value)
        {
            obj.SetValue(ShowAdornerProperty, value);
        }

        public static readonly DependencyProperty ShowAdornerProperty =
            DependencyProperty.RegisterAttached("ShowAdorner", typeof(bool), typeof(HMIKDAButton), new PropertyMetadata(false, ShowAdornerChangedCB));

        public bool ShowAdorner
        {
            get { return (bool)GetValue(ShowAdornerProperty); }
            set { SetValue(ShowAdornerProperty, value); }
        }
        int KDA;
        private static void ShowAdornerChangedCB(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var ele = d as Visual;
            var adolay = AdornerLayer.GetAdornerLayer(ele);

            if (adolay != null)
            {
                var ados = adolay.GetAdorners(ele as UIElement);
                if (ados == null)
                {
                    KDAdorner kdaad = new KDAdorner(ele as UIElement, 0);
                    adolay.Add(kdaad);
                }
                ados = adolay.GetAdorners(ele as UIElement);
                if (ados != null && ados.Count() != 0)
                {
                    var ado = ados.FirstOrDefault() as KDAdorner;
                    ado.ShowImage = (bool)e.NewValue;
                }
            }
        }

        #endregion

    }



    public class HMIButton : Button, ITagReader, ITagWriter, ITagWindow
    {
        public static readonly DependencyProperty TagReadTextProperty = DependencyProperty.Register("TagReadText", typeof(string), typeof(HMIButton));
        public static readonly DependencyProperty TagWriteTextProperty = DependencyProperty.Register("TagWriteText", typeof(string), typeof(HMIButton));
        public static readonly DependencyProperty TagWindowTextProperty = DependencyProperty.Register("TagWindowText", typeof(string), typeof(HMIButton));
        public static readonly DependencyProperty IsModelProperty = DependencyProperty.Register("IsModel", typeof(bool), typeof(HMIButton));
        public static readonly DependencyProperty IsUniqueProperty = DependencyProperty.Register("IsUnique", typeof(bool), typeof(HMIButton));
        public static readonly DependencyProperty IsPulseProperty = DependencyProperty.Register("IsPulse", typeof(bool), typeof(HMIButton));
        public static readonly DependencyProperty PulseWriteInt16Property =
            DependencyProperty.Register("PulseWriteInt16", typeof(bool), typeof(HMIButton));

        public HMIButton()
        {

        }

        public string[] GetActions()
        {
            return new string[] { TagActions.VISIBLE, TagActions.CAPTION, TagActions.ALARM, TagActions.DEVICENAME };
        }

        [Category("Common")]
        public string TagWindowText
        {
            get
            {
                return (string)base.GetValue(TagWindowTextProperty);
            }
            set
            {
                base.SetValue(TagWindowTextProperty, value);
            }
        }

        [Category("Common")]
        public bool IsModel
        {
            get
            {
                return (bool)base.GetValue(IsModelProperty);
            }
            set
            {
                base.SetValue(IsModelProperty, value);
            }
        }

        [Category("Common")]
        public string TagReadText
        {
            get
            {
                return (string)base.GetValue(TagReadTextProperty);
            }
            set
            {
                base.SetValue(TagReadTextProperty, value);
            }
        }

        [Category("Common")]
        public string TagWriteText
        {
            get
            {
                return (string)base.GetValue(TagWriteTextProperty);
            }
            set
            {
                base.SetValue(TagWriteTextProperty, value);
            }
        }

        [Category("HMI")]
        public bool IsPulse
        {
            get
            {
                return (bool)base.GetValue(IsPulseProperty);
            }
            set
            {
                base.SetValue(IsPulseProperty, value);
            }
        }

        [Category("HMI")]
        public bool PulseWriteInt16
        {
            get
            {
                return (bool)base.GetValue(PulseWriteInt16Property);
            }
            set
            {
                base.SetValue(PulseWriteInt16Property, value);
            }
        }

        [Category("HMI")]
        public bool IsUnique
        {
            get
            {
                return (bool)base.GetValue(IsUniqueProperty);
            }
            set
            {
                base.SetValue(IsUniqueProperty, value);
            }
        }

        protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonUp(e);
            if (PulseWriteInt16)
            {
                if (_funcWrites.Count > 0)
                    _funcWrites.ForEach(x => x(0x2));
            }
            else
            {
                if (_funcWrites.Count > 0)
                    _funcWrites.ForEach(x => x(false));
            }
            e.Handled = false;
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);
            if (_funcints.Count > 0)
                _funcints.ForEach(x => x());
            if (PulseWriteInt16)
            {
                if (_funcWrites.Count > 0)
                    _funcWrites.ForEach(x => x(0x1));
            }
            else
            {
                if (_funcWrites.Count > 0)
                    _funcWrites.ForEach(x => x(true));
            }
        }

        ColorAnimationUsingKeyFrames animation;
        SolidColorBrush brush;

        public Action SetTagReader(string key, Delegate tagChanged)
        {
            switch (key)
            {
                case TagActions.ALARM:
                    var _funcAlarm = tagChanged as Func<bool>;
                    if (_funcAlarm != null)
                    {
                        if (animation == null)
                        {
                            brush = Background as SolidColorBrush;
                            if (brush != null)
                            {
                                brush = brush.Clone();
                                animation = new ColorAnimationUsingKeyFrames
                                {
                                    KeyFrames = new ColorKeyFrameCollection
                                        {
                                            new DiscreteColorKeyFrame(brush.Color, TimeSpan.FromSeconds(0.0)),
                                            new DiscreteColorKeyFrame(Colors.Red, TimeSpan.FromSeconds(0.5)),
                                            new DiscreteColorKeyFrame(brush.Color, TimeSpan.FromSeconds(1))
                                        },
                                    AutoReverse = true,
                                    RepeatBehavior = RepeatBehavior.Forever
                                };
                            }
                        }
                        return delegate
                         {
                             if (brush != null)
                             {
                                 if (_funcAlarm())
                                 {
                                     brush.BeginAnimation(SolidColorBrush.ColorProperty, animation);
                                     Background = brush;
                                 }
                                 else
                                 {
                                     brush.BeginAnimation(SolidColorBrush.ColorProperty, null);
                                     Background = brush;
                                 }
                             }
                         };
                    }
                    else
                        return null;
                case TagActions.VISIBLE:
                    var _funcVisible = tagChanged as Func<bool>;
                    if (_funcVisible != null)
                    {
                        return delegate
                        {
                            this.Visibility = _funcVisible() ? Visibility.Visible : Visibility.Hidden;
                        };
                    }
                    else
                        return null;
                case TagActions.CAPTION:
                    var _funcCaption = tagChanged as Func<string>;
                    if (_funcCaption != null)
                    {
                        return delegate { this.Content = _funcCaption(); };
                    }
                    else
                        return null;
            }
            return null;
        }

        List<Func<object, int>> _funcWrites = new List<Func<object, int>>();
        List<Func<int>> _funcints = new List<Func<int>>();
        public bool SetTagWriter(IEnumerable<Delegate> tagWriter)
        {
            bool ret = true;
            _funcWrites.Clear();
            _funcints.Clear();
            foreach (var item in tagWriter)
            {
                Func<object, int> _funcWrite = item as Func<object, int>;

                if (_funcWrite != null)
                    _funcWrites.Add(_funcWrite);
                else
                {
                    Func<int> _funcint = item as Func<int>;
                    if (_funcint != null)
                        _funcints.Add(_funcint);
                    else
                    {
                        ret = false;
                        break;
                    }
                }
            }
            return ret;
        }

        public IList<ITagLink> Children
        {
            get { return null; }
        }

        public string Node
        {
            get { return this.Name; }
        }



    }

    public class KDAdorner : Adorner
    {
        private VisualCollection _visuals;
        private Canvas _grid;
        private Border _br;

        public static readonly DependencyProperty KDArProperty =
        DependencyProperty.RegisterAttached("KDA", typeof(int), typeof(HMIButton), new PropertyMetadata(0, null));

        private static void ShowAdornerChangedCB(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {

        }

        public int KDA
        {
            get { return (int)GetValue(KDArProperty); }
            set
            {
                SetValue(KDArProperty, value);
            }
        }

        protected override void OnRender(DrawingContext drawingContext)
        {

            base.OnRender(drawingContext);
        }

        void AddNewGrid()
        {
            TextBlock _txt;
            _br = new Border();
            _br.CornerRadius = new CornerRadius(50);
            _br.Background = Brushes.Red;
            _txt = new TextBlock();

            _txt.Text = KDA.ToString();
            _txt.Width = _txt.Height = 20;
            _txt.Foreground = Brushes.White;
            _txt.TextAlignment = TextAlignment.Center;

            _br.Child = _txt;
            _grid = new Canvas();
            _grid.Children.Add(_br);
            _visuals.Add(_grid);

            _grid.Visibility = System.Windows.Visibility.Visible;
        }
        public KDAdorner(UIElement ele, int val = 0)
            : base(ele)
        {
            _visuals = new VisualCollection(this);
            KDA = val;
            AddNewGrid();
        }
        protected override Visual GetVisualChild(int index)
        {
            return _visuals[index];
        }


        bool _ShowImage;
        public bool ShowImage
        {
            get { return _ShowImage; }
            set
            {

                if (value)
                {
                    _grid.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    _grid.Visibility = System.Windows.Visibility.Hidden;
                }
            }
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            _grid.Arrange(new Rect(finalSize));
            _br.Margin = new Thickness(finalSize.Width - 12.5, -12.5, 0, 0);
            return base.ArrangeOverride(finalSize);
        }
        protected override int VisualChildrenCount
        {
            get
            {
                return _visuals.Count;
            }
        }
    }


    /// <summary>
    /// 连线过程 装饰器提供者
    /// </summary>
    class PidasdnAdorner : Adorner
    {
        private VisualCollection _visuals;
        private Canvas _grid;
        private Border _br;
        LinkableControl designObject;
        /// <summary>
        /// 装饰器 == 选中的控件
        /// </summary>
        ControlAdorner adorner;
        Panel designCanvas;

        public PidasdnAdorner(UIElement ele, int val = 0)
            : base(ele)
        {
            _visuals = new VisualCollection(this);
            FanPin f = ele as FanPin;
            _visuals.Add(f);

        }
        protected override Visual GetVisualChild(int index)
        {
            return _visuals[index];
        }


        bool _ShowImage;
        public bool ShowImage
        {
            get { return _ShowImage; }
            set
            {

                if (value)
                {
                    _grid.Visibility = System.Windows.Visibility.Visible;
                }
                else
                {
                    _grid.Visibility = System.Windows.Visibility.Hidden;
                }
            }
        }

        protected override Size ArrangeOverride(Size finalSize)
        {
            _grid.Arrange(new Rect(finalSize));
            _br.Margin = new Thickness(finalSize.Width - 12.5, -12.5, 0, 0);
            return base.ArrangeOverride(finalSize);
        }
        protected override int VisualChildrenCount
        {
            get
            {
                return _visuals.Count;
            }
        }



        /// <summary>
        /// 方向绑定Map
        /// </summary>
        static readonly Dictionary<ConnectOrientation, string> omap = new Dictionary<ConnectOrientation, string>
        { { ConnectOrientation.Left, "LeftPin" }, { ConnectOrientation.Right, "RightPin" },
        { ConnectOrientation.Top, "TopPin" }, { ConnectOrientation.Bottom, "BottomPin" },{ ConnectOrientation.None, "" } };
        void pinAdorner_MouseUp(object sender, MouseButtonEventArgs e)
        {
            /*
            var pinAdorner = sender as PinAdorner;
            if (pinAdorner.HitPin != null)
            {
                LinkableControl targetObject = pinAdorner.HitLinkableControl;
                LinkPin lp1 = pinAdorner.SourcePin;
                LinkPin lp2 = pinAdorner.HitPin;

                ConnectInfo srcinfo = lp1.GetInfo();
                ConnectInfo taginfo = lp2.GetInfo();

                LinkLine line = new LinkLine(srcinfo, taginfo);
                //Panel.SetZIndex(line, designCanvas.Children.Count);

                Binding bi1 = new Binding(omap[srcinfo.Orient]);
                bi1.ElementName = designObject.Name;
                line.SetBinding(LinkLine.OriginInfoProperty, bi1);
                Binding bi2 = new Binding(omap[taginfo.Orient]);
                bi2.ElementName = targetObject.Name;
                line.SetBinding(LinkLine.TargetInfoProperty, bi2);

                var CanvasModelItem = AdornerProperties.GetModel(adorner).Parent;
                ModelItemCollection myControls = CanvasModelItem.Properties["Children"].Collection;
                ModelItem myLinkLine = myControls.Add(line);

            }
            if (pinAdorner.HitLinkableControl != null)
            {
                pinAdorner.HitLinkableControl.IsLinkDragOver = false;
            }

            hitPin = null;
            if (adorner.IsMouseCaptured) adorner.ReleaseMouseCapture();
            _panel.Children.Remove(pinAdorner);
            */
        }



    }



}
